
package org.vasil.update.mongodb

import com.mongodb.BasicDBObject

class DBService {
	
    def databaseService = new DatabaseService()

    def doInsertItems = { items ->
        
        def db = databaseService.db(), cursor
        
        items.each { sku, item ->

            //if(item.getResult() == 'Ok' && item.utils['action'] == 'desc') {
                
                try {
                    doUpdateCategory(db, sku, item) // first check category and subcategory
                    
                    cursor = db.items.findOne([sku: sku], [_id: 0])
                    //println "cursor=${cursor}"
                    if(cursor) { // update
                        //println "need update cursor:\n${cursor}\nmap=${item.getMap()}"
                        def what = whatFieldUpdate(cursor, item.getMap())
                        //println "result=[\$set: ${what}]"
                        db.items.update([sku: sku], [$set: what, $inc: [upcount: 1]])
                    }
                    else { // insert
                        //println "need insert ${item.getMap()}"
                        db.items << item.getMap()
                    }
                }
                catch(e) {
                    println "Error doInsertItems ${sku}:\n${e}"
                }
            //} // if
        } // each
    }

    // delete all sku items from category, dec count and set item active='D'
    def doDeleteItems = { items ->

        def db = databaseService.db()
        items.each { sku, item ->

            //if(item.getResult() == 'Ok' && item.utils['action'] == 'delete') {
                def doc
                try {
                    db.categories.update(
                        ['nodes.items': sku],
                        [$pull: ['nodes.$.items': sku], $inc: [count: -1, 'nodes.$.count': -1]]
                        
                    ) //[multi:true]
                    // test
                    doc = db.categories.find(['nodes.items': sku], [node1: 1])
                    println "doDeleteItems categories doc=${doc}"

                    db.items.update(
                        [sku: sku],
                        [$set: [active: 'D'], $inc: [upcount: 1]]
                    )//, [multi:true]
                    // test
                    doc = db.items.find([sku: sku], [sku: 1, active: 1])
                    println "doDeleteItems items doc=${doc}"
                }
                catch(e) {
                    println "Error doDeleteItems ${sku}:\n${e}"
                }
            //} // if
        } // each
    }

    // insert or update categore, subcat and item, count
    def doUpdateCategory = { db, sku, item ->

        def cursor = db.categories.findOne(node0: item.category.parentid)
        //println "node0 update category cursor=${cursor}"
        if(cursor) { // update
            //println "node0 nodes=${cursor.nodes}"

            if(item.category.catname != cursor.name) {
                db.categories.update([node0: item.category.parentid], [$set: [name: item.category.parentname]]) // update name
            }

            def node1 = cursor.nodes.find { it.node1 == item.category.categoryid }
            //println "node1=${node1}"
            if(node1) { // update
                def res = [:]
                if(node1.name != item.category.catname)         res << ['nodes.$.name': item.category.catname]
                if(node1.pref.name1 != item.category.prefname1) res << ['nodes.$.pref.name1': item.category.prefname1]
                if(node1.pref.name2 != item.category.prefname2) res << ['nodes.$.pref.name2': item.category.prefname2]
                if(node1.pref.name3 != item.category.prefname3) res << ['nodes.$.pref.name3': item.category.prefname3]
                if(node1.pref.name4 != item.category.prefname4) res << ['nodes.$.pref.name4': item.category.prefname4]
                if(node1.pref.name5 != item.category.prefname5) res << ['nodes.$.pref.name5': item.category.prefname5]

                def haveItem = node1.items.find { it == sku } // if have item no need insert
                if(!haveItem) { // dont have -> insert
                    db.categories.update(
                        [node0: item.category.parentid, 'nodes.node1': item.category.categoryid],
                        [$push:['nodes.$.items': sku],
                            $inc: [count: 1, 'nodes.$.count': 1]
                        ]
                    )
                }

                db.categories.update(
                    [node0: item.category.parentid, 'nodes.node1': item.category.categoryid],
                    [$set:res]
                )
            }
            else { // insert new suncat
                db.categories.update(
                    [node0: item.category.parentid],
                    [$push: [
                        nodes: [
                        node1: item.category.categoryid,
                        name: item.category.catname,
                        count: 1,
                        items:[ sku ], // need check active or not
                        pref: [
                            name1: item.category.prefname1,
                            name2: item.category.prefname2,
                            name3: item.category.prefname3,
                            name4: item.category.prefname4,
                            name5: item.category.prefname5
                        ],
                        active: true
                        ]
                    ],
                    $inc: [count: 1]])
            }

            //if(item.category. != cursor.)       res << [: cursor.]
        }
        else { // insert new
            //println "insert category item.category.parentid=${item.category.parentid} : item.category.categoryid=${item.category.categoryid}"
            db.categories.insert([
                node0: item.category.parentid,
                name: item.category.parentname,
                count: 1,
                nodes:[[
                    node1: item.category.categoryid,
                    name: item.category.catname,
                    count: 1,
                    items:[ sku ], // need check active or not
                    pref: [
                        name1: item.category.prefname1,
                        name2: item.category.prefname2,
                        name3: item.category.prefname3,
                        name4: item.category.prefname4,
                        name5: item.category.prefname5
                    ],
                    active: true
                ]],
                active: true
            ])
        }
    }


    def whatFieldUpdate = { o, n ->
        //println "whatFieldUpdate:\no=${o}\nn=${n}"
        //def start = System.currentTimeMillis()
        def res = [:]
//        words.each { word ->
//            res = (o[word] != n[word]) ? ["${word}": n[word]] : null
//        }
        if(o.etilid != n.etilid)                         res << [etilid: n.etilid]
        if(o.quantity.stock != n.quantity.stock)         res << ['quantity.stock': n.quantity.stock]
        res << ['quantity.reserv': 0]
        if(o.stock != n.stock)                           res << [stock: n.stock]
        if(o.keywords != n.keywords)                     res << [keywords: n.keywords]
        if(o.weight != n.weight)                         res << [weight: n.weight]
        if(o.drone != n.drone)                           res << [drone: n.drone]
        if(o.json != n.json)                             res << [json: n.json]
        if(o.sockdate != n.sockdate)                     res << [sockdate: n.sockdate]
        if(o.active != n.active)                         res << [active: n.active]
        if(o.names.name != n.names.name)                 res << ['names.name': n.names.name]
        if(o.names.a != n.names.a)                       res << ['names.a': n.names.a]
        if(o.names.b != n.names.b)                       res << ['names.b': n.names.b]
        if(o.mfr.name != n.mfr.name)                     res << ['mfr.name': n.mfr.name]
        if(o.mfr.number != n.mfr.number)                 res << ['mfr.number': n.mfr.number]
        if(o.mfr.link != n.mfr.link)                     res << ['mfr.link': n.mfr.link]
        if(o.price.cost != n.price.cost)                 res << ['price.cost': n.price.cost]
        if(o.price.sell != n.price.sell)                 res << ['price.sell': n.price.sell]
        if(o.price.hot != n.price.hot)                   res << ['price.hot': n.price.hot]
        if(o.reseller.price1 != n.reseller.price1)       res << ['reseller.price1': n.reseller.price1]
        if(o.reseller.price2 != n.reseller.price2)       res << ['reseller.price2': n.reseller.price2]
        if(o.reseller.price3 != n.reseller.price3)       res << ['reseller.price3': n.reseller.price3]
        if(o.reseller.qty2 != n.reseller.qty2)           res << ['reseller.qty2': n.reseller.qty2]
        if(o.reseller.qty3 != n.reseller.qty3)           res << ['reseller.qty3': n.reseller.qty3]
        if(o.warranty.mask != n.warranty.mask)           res << ['warranty.mask': n.warranty.mask]
        if(o.warranty.price1 != n.warranty.price1)       res << ['warranty.price1': n.warranty.price1]
        if(o.warranty.price2 != n.warranty.price2)       res << ['warranty.price2': n.warranty.price2]
        if(o.warranty.price3 != n.warranty.price3)       res << ['warranty.price3': n.warranty.price3]
        if(o.vendor.alias != n.vendor.alias)             res << ['vendor.alias': n.vendor.alias]
        if(o.vendor.name != n.vendor.name)               res << ['vendor.name': n.vendor.name]
        if(o.pics != n.pics)                             res << [imgs: n.pics]
        if(o.packag.include != n.packag.include)         res << ['packag.include': n.packag.include]
        if(o.packag.comment != n.packag.comment)         res << ['packag.comment': n.packag.comment]
        if(o.google.group != n.google.group)             res << ['google.group': n.google.group]
        if(o.preference.p1 != n.preference.p1)           res << ['preference.p1': n.preference.p1]
        if(o.preference.p2 != n.preference.p2)           res << ['preference.p2': n.preference.p2]
        if(o.preference.p3 != n.preference.p3)           res << ['preference.p3': n.preference.p3]
        if(o.preference.p4 != n.preference.p4)           res << ['preference.p4': n.preference.p4]
        if(o.preference.p5 != n.preference.p5)           res << ['preference.p5': n.preference.p5]
        if(o.advert.name != n.advert.name)               res << ['advert.name': n.advert.name]
        if(o.advert.price != n.advert.price)             res << ['advert.price': n.advert.price]
        if(o.advert.mfrname != n.advert.mfrname)         res << ['advert.mfrname': n.advert.mfrname]
        if(o.advert.mfrnumber != n.advert.mfrnumber)     res << ['advert.mfrnumber': n.advert.mfrnumber]
        if(o.advert.keywords != n.advert.keywords)       res << ['advert.keywords': n.advert.keywords]
        if(o.advert.cnet != n.advert.cnet)               res << ['advert.cnet': n.advert.cnet]
        if(o.advert.grabber != n.advert.grabber)         res << ['advert.grabber': n.advert.grabber]
        if(o.advert.bizrate != n.advert.bizrate)         res << ['advert.bizrate': n.advert.bizrate]
        if(o.advert.nextag != n.advert.nextag)           res << ['advert.nextag': n.advert.nextag]
        if(o.advert.shopping != n.advert.shopping)       res << ['advert.shopping': n.advert.shopping]
        if(o.advert.powersource != n.advert.powersource) res << ['advert.powersource': n.advert.powersource]
        if(o.advert.froogle != n.advert.froogle)         res << ['advert.froogle': n.advert.froogle]
        if(o.advert.cj != n.advert.cj)                   res << ['advert.cj': n.advert.cj]
        if(o.advert.gadgetpage != n.advert.gadgetpage)   res << ['advert.gadgetpage': n.advert.gadgetpage]
        if(o.advert.upccode != n.advert.upccode)         res << ['advert.upccode': n.advert.upccode]
        if(o.banner.special != n.banner.special)         res << ['banner.special': n.banner.special]
        if(o.banner.closeout != n.banner.closeout)       res << ['banner.closeout': n.banner.closeout]
        if(o.banner.comingsoon != n.banner.comingsoon)   res << ['banner.comingsoon': n.banner.comingsoon]
        if(o.banner.bestprice != n.banner.bestprice)     res << ['banner.bestprice': n.banner.bestprice]
        if(o.banner.firstpage != n.banner.firstpage)     res << ['banner.firstpage': n.banner.firstpage]
        if(o.banner.catpage != n.banner.catpage)         res << ['banner.catpage': n.banner.catpage]
        if(o.banner.ebay != n.banner.ebay)               res << ['banner.ebay': n.banner.ebay]
        if(o.banner.lot != n.banner.lot)                 res << ['banner.lot': n.banner.lot]
//        if(o. != n.)       res << [: n.]

        res << [update: new Date()]

        //println "Time: ${System.currentTimeMillis() - start}ms."
        return res
    }

    // Time excecution
    def benchmark = { closure ->
        start = System.currentTimeMillis()
        closure.call()
        return System.currentTimeMillis() - start
    }

}

